package qualomelhor.game;

import static playn.core.PlayN.assets;
import static playn.core.PlayN.graphics;
import java.util.LinkedList;
import playn.core.AssetWatcher;
import playn.core.Image;
import playn.core.ImageLayer;
import qualomelhor.database.Avatar.Olho;
import qualomelhor.database.Avatar.PosicaoOlhoBoneco;
import qualomelhor.database.SequenciaExpressaoDB;

public class Olhos {

	private static int tempoIntervaloPisca = 50;

	private ImageLayer layerOlhoD;
	private ImageLayer layerOlhoE;
	private Image imgOlho;
	private int scaleX, scaleY;
	private float xOlhoD, yOlhoD, xOlhoE, yOlhoE, angle;
	private boolean piscando = false;
	private int piscaCount = 0;
	private Image[] imgPisca;
	private byte tempoPisca = 0;
	private PosicaoOlhoBoneco pOlhoAtual = PosicaoOlhoBoneco.OLHO_CENTRO;
	private Olho estiloOlhoAtual = Olho.OLHO1;
	private boolean trocandoOlho = false;
	private LinkedList<PosicaoOlhoBoneco> listPosicaoOlhoPendente = new LinkedList<PosicaoOlhoBoneco>();
	private LinkedList<Olho> listEstiloOlhoPendente = new LinkedList<Olho>();

	private boolean trocandoTemporario = false;
	private float tempoTrocaTemp = 0;
	private float tempoTrocaTempDest = 0;
	private PosicaoOlhoBoneco posOlhoTemp;

	private int sclAtualX = 1, sclAtualY = 1;

	public Olhos (float xD, float yD, float xE, float yE, Image imgOlho, int scX, int scY) {
		this.imgOlho = imgOlho;
		this.xOlhoD = xD;
		this.yOlhoD = yD;
		this.xOlhoE = xE;
		this.yOlhoE = yE;		
		this.scaleX = scX;
		this.scaleY = scY;
		layerOlhoD = graphics().createImageLayer(imgOlho);
		layerOlhoE = graphics().createImageLayer(imgOlho);
		setImage(imgOlho);
	}

	public boolean getTrocandoOlho() {
		return trocandoOlho;
	}

	public void update(float delta) {		
		if (piscando) {
			if (tempoPisca >= tempoIntervaloPisca) {
				tempoPisca = 0;
				if (piscaCount <= 2) {
					getLayerOlhoD().setImage(imgPisca[piscaCount]);
					getLayerOlhoE().setImage(imgPisca[piscaCount]);
					piscaCount++;
					//trocaMovimentoSobrancelha(MovimentoSobrancelha.SOBRANCELHA_AMBAS_ABAIXO);
				} else {
					piscando = false;
					setImage(imgOlho);
					//trocaPosicaoOlho(posOlhoAtual);
				}
			} else {
				tempoPisca += delta;
			}
			
		} else if (!trocandoOlho) {
			if (listPosicaoOlhoPendente.size() > 0) {
				trocaPosicaoOlho(listPosicaoOlhoPendente.removeFirst());
			} else if (listEstiloOlhoPendente.size() > 0) {
				trocaEstiloOlho(listEstiloOlhoPendente.removeFirst());
			}

		} else if (trocandoTemporario) {
			if (tempoTrocaTemp > tempoTrocaTempDest) {
				// volta pra posicao anterior
				trocaPosicaoOlho(posOlhoTemp);
				trocandoTemporario = false;
			} else {
				tempoTrocaTemp += delta;
			}
		}

		//layerOlhoD.setScale(scaleX * layerOlhoD.transform().scaleX(), scaleY * layerOlhoD.transform().scaleY());
		//layerOlhoE.setScale(scaleX * layerOlhoE.transform().scaleX(), scaleY * layerOlhoE.transform().scaleY());
		int newSclX = 1, newSclY = 1;
		if (scaleX != sclAtualX) {
			newSclX = -1;
		}
		if (scaleY != sclAtualY) {
			newSclY = -1;
		}

		String str = "scale(X,Y) correto = (" + scaleX + ", " + scaleY + ") scale Atual (X,Y) = (" + layerOlhoD.transform().scaleX() + "," + layerOlhoD.transform().scaleY() + "), Multiplicador (X,Y): (" + newSclX + "," + newSclY + ")";
		//TestePlayN.setMessageBox(str);

		layerOlhoD.setScale(newSclX, newSclY);
		layerOlhoE.setScale(newSclX, newSclY);
		sclAtualX *= newSclX;
		sclAtualY *= newSclY;
		//if (layerOlhoD.transform().scaleX() < 0) {
			//Window.alert(str + "\n\n" + "scale(X,Y) correto = (" + scaleX + ", " + scaleY + ") scale Atual (X,Y) = (" + layerOlhoD.transform().scaleX() + "," + layerOlhoD.transform().scaleY() + "), Multiplicador (X,Y): (" + newSclX + "," + newSclY + ")");
		//}

		float xE = xOlhoE, yE = yOlhoE, xD = xOlhoD, yD = yOlhoD; 

		if (sclAtualX == -1) {
			xE = xOlhoE + imgOlho.width();
			xD = xOlhoD + imgOlho.width();
		}
		if (sclAtualY == -1) {
			yE = yOlhoE + imgOlho.height();
			yD = yOlhoD + imgOlho.height();
		}
		layerOlhoE.setTranslation(xE + estiloOlhoAtual.getAproximacaoOlho(), yE);
		layerOlhoD.setTranslation(xD - estiloOlhoAtual.getAproximacaoOlho(), yD);	
	}

	public void paint(float alpha) {
	}

	public ImageLayer getLayerOlhoD() {
		return layerOlhoD;
	}

	public ImageLayer getLayerOlhoE() {
		return layerOlhoE;
	}

	public float getOlhoWidth() {
		return imgOlho.width();
	}

	public float getOlhoHeight() {
		return imgOlho.height();
	}

	public int getEstiloOlhoId() {
		return estiloOlhoAtual.getId();
	}

	public Image getImage() {
		return imgOlho;
	}

	public float getXOlhoD() {
		return xOlhoD;
	}

	public float getYOlhoD() {
		return yOlhoD;
	}

	public float getXOlhoE() {
		return xOlhoE;
	}

	public float getYOlhoE() {
		return yOlhoE;
	}

	public PosicaoOlhoBoneco getPosicaoOlhoAtual() {
		return pOlhoAtual;
	}

	public Olho getEstiloOlhoAtual() {
		return estiloOlhoAtual;
	}

	public void setImage(Image imgOlho) {
		this.imgOlho = imgOlho;
		layerOlhoD.setImage(this.imgOlho);
		layerOlhoE.setImage(this.imgOlho);
	}

	public void setScale(int scX, int scY) {
		this.scaleX = scX;
		this.scaleY = scY;
	}

	public void setPositionOlhoD (float x, float y) {
		this.xOlhoD = x;
		this.yOlhoD = y;
	}

	public void setPositionOlhoE (float x, float y) {
		this.xOlhoE = x;
		this.yOlhoE = y;
	}

	public void setAngle(float angle) {
		this.angle = angle;
	}

	public void pisca() {
		imgPisca = new Image[3];

		AssetWatcher as = new AssetWatcher(new AssetWatcher.Listener() {
			@Override
			public void error(Throwable e) {
				piscando = false;
				piscaCount = 3;
			}

			@Override
			public void done() {
				piscando = true;
				piscaCount = 1;
			}
		});

		for (int i = 0; i < 3; i++) {
			imgPisca[i] = assets().getImage("/images/avatar/olho/" + estiloOlhoAtual.getId() + "/olho" + estiloOlhoAtual.getId() + "_pisca" + (i + 1) + ".png");
			as.add(imgPisca[i]);
		}
		as.start();
	}

	public void trocaEstiloOlho(final Olho olho) {
		if (!trocandoOlho) {
			trocandoOlho = true;

			final Image imgOlho = assets().getImage("/images/avatar/olho/" + olho.getId() + "/olho" + olho.getId() + pOlhoAtual.getArquivo());

			AssetWatcher as = new AssetWatcher(new AssetWatcher.Listener() {
				@Override
				public void error(Throwable e) {
					System.out.println("erro ao carregar a imagem..");
					trocandoOlho = false;
				}

				@Override
				public void done() {
					setImage(imgOlho);
					estiloOlhoAtual = olho;
					trocandoOlho = false;
				}
			});
			as.add(imgOlho);
			as.start();
		} else {
			//Agendando para executar no futuro
			listEstiloOlhoPendente.add(olho);
		}
	}

	public void trocaPosicaoOlho(final PosicaoOlhoBoneco pos) {
		if (!trocandoOlho) {
			trocandoOlho = true;

			//Window.alert("trocando olho.." + pos.getArquivo());
			final Image imgOlhoPos = assets().getImage("/images/avatar/olho/" + estiloOlhoAtual.getId() + "/olho" + estiloOlhoAtual.getId() + pos.getArquivo());

			AssetWatcher as = new AssetWatcher(new AssetWatcher.Listener() {
				@Override
				public void error(Throwable e) {
					System.out.println("erro ao carregar a imagem..");
					trocandoOlho = false;
				}

				@Override
				public void done() {
					setImage(imgOlhoPos);
					pOlhoAtual = pos;
					setScale(pos.getFatorX(), pos.getFatorY());
					trocandoOlho = false;
				}
			});
			as.add(imgOlhoPos);
			as.start();
		} else {
			listPosicaoOlhoPendente.add(pos);
		}
	}

	public void trocaOlhoTemporario(final PosicaoOlhoBoneco posOlho, int tempo) {
		trocandoTemporario = true;
		tempoTrocaTempDest = tempo;
		tempoTrocaTemp = 0;
		posOlhoTemp = getPosicaoOlhoAtual();
		trocaPosicaoOlho(posOlho);
	}
}